Entity References

In a previous chapter we discussed entities in relation to storage objects (i.e. physical files) that can be referenced within our XML documents.  In this chapter we discussed predefined entities in relation to markup characters.  We are going to a step further in our coverage of entities by discussing internal entities.

Internal entities are declarations that look like character references that you can define.  They work very similar to macros in that you can use them to substitute text inside of your XML document.  The syntax for an internal entity is as follows:

<!ENTITY entity.name “replacement text”>

Notice that the markup begins with a <! And does not require any termination character (/).  When the XML document is processed, anytime it encounters the string “&entity.name” it automatically replaces it with the text in quotes.  

Let’s look at an XML sample that uses internal Entities.

<!ENTITY example1 "John Doe">
. . . 
<element1>&example1;</element1>
. . .

The advantages of using internal entities are obvious.  When used correctly, this can save you a lot of time and typing.  You can make the replacement string as long as you like.  But beware the pitfalls.  Remember that XML is parsed by the processor and substitutions are completed before the file is parsed for content.  This can lead to interesting problems if we do not understand this point.  For example, let’s look at the following entity.

<!ENTITY example2 "John &#38; Jane">
. . . 
<element2>&example2</element2>

The goal would be to substitute “&example2” with the string “John & Jane”.  There is just one problem.  Once the substitution is complete, the XML processor is going to report an error in the line due to invalid markup from the use of the character “&”.  To get around the problem, we must “double-up” the character reference.  The correct way to specify the entity would be as follows:

<!ENTITY example2 "John &#38;#38; Jane">
. . . 
<element2>&example2;</element2>

Here is how the XML processor would handle it.

The processor would see the entity name “example2” and replace all occurrences of the text “&example2” with &#38; (the first &#38 is removed by the processor during the replacement).

Once the first &#38 is removed, it is replaced with an ampersand (&), leaving &#38.

When the processor encounters the &#38 the second time, it replaces it with an ampersand (&).

This causes the entity to work as we intend.  Alternately, we could use the &amp; string instead of the hex value.  This does not need to be doubled up.

<!ENTITY example3 “John &amp; Jane”>
. . . 
<element3>&example3;</element3>

Warning:	Be careful when using internal entities to make sure that your structures are synchronous (i.e. all of your tags match up).   Try not to use entities that begin or end a tag without the other matching it or you may run into some interesting debugging problems!